﻿#include "pagefile.h"
#include <boost/format.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>  
#include "../../liblog/Include/liblog.h"

const char* db_name = "record.db";

CPagefile::CPagefile()
: pagefile_db(NULL)
{

}

CPagefile::~CPagefile()
{

}

CPagefile& CPagefile::GetInstance()
{
	static CPagefile pagefile;
	return pagefile;
}

inline int sqlite3_affect_exec(sqlite3* db, const char *sql,char **errmsg)
{
	return sqlite3_exec(db, sql, NULL, NULL, errmsg);
}

int CPagefile::Start()
{
	int ret = sqlite3_open_v2(db_name, &pagefile_db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX, NULL);
	if (ret != SQLITE_OK)
	{
		LogError(("%s failed.error:%s.\r\n", __PRETTY_FUNCTION__, sqlite3_errstr(ret)));
		return -1;
	}
    
    //begin:add creat table device_info by ypj, at 2017/6/19
	char* msg = NULL;
	ret = sqlite3_affect_exec(pagefile_db,
		"CREATE TABLE IF NOT EXISTS DEVICE_INFO\
		 (DEVICE_ID VARCHAR (20) PRIMARY KEY,HARDWARE_ID TEXT,DEVICE_KEY VARCHAR(24),SNED_SN INT);",&msg);
	if (ret != SQLITE_OK)
	{
		LogError(("%s failed.code:%d error:%s.\r\n", __PRETTY_FUNCTION__, ret, msg));
		sqlite3_free(msg);
		sqlite3_close_v2(pagefile_db);
		pagefile_db = NULL;
		return -1;
	}
    //end
	return 0;
}

int CPagefile::Stop()
{
	sqlite3_close_v2(pagefile_db);
	pagefile_db = NULL;
	return 0;
}


bool CPagefile::GetNewDeviceInfo(const std::string hardwareid, std::string &deviceid, std::string &devicekey)
{
    if (!pagefile_db)
        return false;

    //sqlite3_prepare_v2
    
	const char* select_sql = "SELECT DEVICE_ID, DEVICE_KEY FROM DEVICE_INFO WHERE HARDWARE_ID = \'%s\';";
 	std::string sql = boost::str(boost::format(select_sql) % hardwareid);
    
	int nRow = 0, nColumn = 0;
	char* msg = NULL, **resultSet = NULL;
	int ret = sqlite3_get_table(pagefile_db, sql.c_str(), &resultSet, &nRow, &nColumn, &msg);
	if (ret != SQLITE_OK)
	{
		LogError(("%s:sql %s, failed.code:%d error:%s.\r\n", __PRETTY_FUNCTION__, sql.c_str(), ret, msg));
		sqlite3_free(msg);
		return false;
	}
    std::string strdeviceid = "";
    std::string strdevicekey = "";
    if (nRow > 0)
    {
        strdeviceid = std::string(resultSet[1 + 1]);
        strdevicekey = std::string(resultSet[1 + 2]);
        sqlite3_free_table(resultSet);
    }
    else
    {
        const char* select_sql1 = "SELECT DEVICE_ID, DEVICE_KEY FROM DEVICE_INFO WHERE HARDWARE_ID = \"\" OR HARDWARE_ID IS NULL;";
        ret = sqlite3_get_table(pagefile_db, select_sql1, &resultSet, &nRow, &nColumn, &msg);
        if (ret != SQLITE_OK)
        {
            LogError(("%s sql:&s failed.code:%d error:%s.\r\n", __PRETTY_FUNCTION__, select_sql1, ret, msg));
            sqlite3_free(msg);
            return false;
        }
        
        if (nRow > 0)
        {
            strdeviceid = std::string(resultSet[1 + 1]);
            strdevicekey = std::string(resultSet[1 + 2]);
            const char* update_sql =
                "UPDATE DEVICE_INFO SET HARDWARE_ID = \'%s\' WHERE DEVICE_ID=\'%s\';";
            
            std::string sql = boost::str(boost::format(update_sql) % hardwareid % strdeviceid);
            sqlite3_free_table(resultSet);
            int ret = sqlite3_affect_exec(pagefile_db, sql.c_str(),&msg);
            if (ret != SQLITE_OK)
            {
                LogError(("%s:sql %s failed.code:%d error:%s.\r\n", __PRETTY_FUNCTION__, sql.c_str(), ret, msg));
                sqlite3_free(msg);
                return false;
            }
        }
        else
        {
            LogError(("%s:设备ID已用完,请申请新的设备ID\n", hardwareid.c_str()));
            return false;
        }
    }
    deviceid = strdeviceid;
    devicekey = strdevicekey;
    return true;
}


int CPagefile::GetSendSnByHardid(const std::string deviceid)
{
	const char* select_sql = "SELECT SEND_SN FROM DEVICE_INFO WHERE DEVICE_ID = \'%s\';";
 	std::string sql = boost::str(boost::format(select_sql) % deviceid);
	int nRow = 0, nColumn = 0;
	char* msg = NULL, **resultSet = NULL;
	int ret = sqlite3_get_table(pagefile_db, sql.c_str(), &resultSet, &nRow, &nColumn, &msg);
	if (ret != SQLITE_OK)
	{
		LogError(("%s:sql %s, failed.code:%d error:%s.\r\n", __PRETTY_FUNCTION__, sql.c_str(), ret, msg));
		sqlite3_free(msg);
		return -1;
	}
    int sn = boost::lexical_cast<int>(resultSet[1]);
    sn++;
	sqlite3_free_table(resultSet);

    
    const char* update_sql =
        "UPDATE DEVICE_INFO SET SEND_SN = %d WHERE DEVICE_ID=\'%s\';";
    sql = boost::str(boost::format(update_sql) % sn % deviceid);
    ret = sqlite3_affect_exec(pagefile_db, sql.c_str(),&msg);
    if (ret != SQLITE_OK)
    {
        LogError(("%s:sql %s failed.code:%d error:%s.\r\n", __PRETTY_FUNCTION__, sql.c_str(), ret, msg));
        sqlite3_free(msg);
        return -1;
    }

    return sn;
}



